package pers.cj.pdos.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import pers.cj.pdos.cache.CacheData;
import pers.cj.pdos.cache.CacheRemove;
import pers.cj.pdos.cache.CacheRemoveByIds;
import pers.cj.pdos.cache.CacheRemoveMore;
import pers.cj.pdos.constant.OrderType;
import pers.cj.pdos.controller.GoodsSnController;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.exception.CustomException;
import pers.cj.pdos.mapper.*;
import pers.cj.pdos.service.IGoodsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.cj.pdos.utils.*;
import pers.cj.pdos.vo.CountVo;
import pers.cj.pdos.vo.GoodsVo;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {
    @Autowired
    GoodsMapper goodsMapper;
    @Autowired
    GoodsAttrMapper goodsAttrMapper;
    @Autowired
    private GoodsUnitMapper goodsUnitMapper;
    @Autowired
    private GoodsHouseWarnMapper goodsHouseWarnMapper;
    @Autowired
    private TypeMapper typeMapper;
    @Autowired
    private UnitMapper unitMapper;
    @Autowired
    private AttrMapper attrMapper;
    @Autowired
    GoodsSnMapper goodsSnMapper;
    @Autowired
    GoodsSnLogMapper goodsSnLogMapper;
    @Autowired
    OrderRuleMapper orderRuleMapper;
    @Autowired
    PacketGoodsMapper packetGoodsMapper;
    @Autowired
    GoodsInitMapper goodsInitMapper;
    @Autowired
    GoodsStockMapper goodsStockMapper;
    @Autowired
    GoodsCostMapper goodsCostMapper;

    @Override
    public List<Goods> list(String companyId) {
        return goodsMapper.selectList(new QueryWrapper<Goods>().eq("company_id",companyId));
    }

    @Override
    public List<GoodsVo> listVoByIds(List<String> ids) {
        return goodsMapper.listVoByIds(ids);
    }

    @Override
    public List<GoodsVo> listVoForCheckHouse(String companyId, Integer page, Integer limit, Integer status, String search, String typeId, String no, String name, String attr, String norms, String remark, Boolean sn, String houseId) {
        if (Utils.isEmpty(houseId)) {
            throw new CustomException("仓库id不能为空");
        }
        return goodsMapper.listVoForCheckHouse(companyId,
                Utils.genPage(page,limit),
                limit,
                status,
                Utils.genLikeData(search),
                typeId,
                no,
                name,
                attr,
                norms,
                remark,
                sn,
                houseId);
    }

    @Override
    public List<GoodsVo> listVoWithStockPage(String companyId, Integer page, Integer limit, Integer status, String search, String typeId, String no, String name, String attr, String norms, String remark, Boolean sn, String houseId) {
        if (Utils.isEmpty(houseId)) {
            throw new CustomException("仓库id不能为空");
        }
        return goodsMapper.listVoWithStock(companyId,
                Utils.genPage(page,limit),
                limit,
                status,
                Utils.genLikeData(search),
                typeId,
                no,
                name,
                attr,
                norms,
                remark,
                sn,
                houseId);
    }

    @Override
    public List<GoodsVo> listVoForInit(String companyId, Integer page, Integer limit, String search, String storeId, String houseId) {
        return goodsMapper.listVoForInit(companyId, Utils.genPage(page,limit), limit, search, storeId, houseId);
    }

    @Override
    public Long countForInit(String companyId, String search, String storeId, String houseId) {
        return goodsMapper.countForInit(companyId, search, storeId, houseId);
    }

    @Override
    public List<GoodsVo> listVoPage(String companyId,Integer page, Integer limit, Integer status , String search,
                                    String typeId, String no, String name,String attr,String norms, String remark, Boolean sn) {
        return goodsMapper.listVo(companyId,
                Utils.genPage(page,limit),
                limit,
                status,
                Utils.genLikeData(search),
                typeId,
                no,
                name,
                attr,
                norms,
                remark,
                sn);
    }

    @Override
    public long count(String companyId,Integer status , String search,  String typeId, String no, String name,String attr,String norms, String remark, Boolean sn) {
        return goodsMapper.count(companyId,
                status,
                Utils.genLikeData(search),
                typeId,
                no,
                name,
                attr,
                norms,
                remark,
                sn);
    }

    @Override
    public GoodsVo getVoById(String id) {
        return goodsMapper.getVoById(id);
    }

    @Override
    public boolean check(String id) {
        return Utils.check(goodsMapper.check(id));
    }

    @Override
    public Map<String,Long> check(List<Goods> goodsList) {
        List<CountVo> countVoList = goodsMapper.checkList(goodsList);
        Map<String,Long> map = new HashMap<>();
        for (CountVo countVo : countVoList) {
            if (!countVo.getId().equals("0") ) {
                Long count = map.get(countVo.getId())==null ? Long.valueOf(0) : map.get(countVo.getId());
                count += countVo.getCount();
                map.put(countVo.getId(), count);
            }
        }
        return map;
    }

    @Override
    public void save(Goods goods, List<GoodsAttr> goodsAttrList, List<GoodsUnit> goodsUnitList,
                     List<GoodsHouseWarn> goodsHouseWarnList,List<GoodsInit> goodsInitList,
                     List<GoodsSn> goodsSnList,List<GoodsSnLog> goodsSnLogList) {
        goodsMapper.insert(goods);

        //添加
        if (!Utils.isEmpty(goodsAttrList)) {
            goodsAttrMapper.insertBatch(goodsAttrList);
        }
        if (!Utils.isEmpty(goodsUnitList)) {
            goodsUnitMapper.insertBatch(goodsUnitList);
        }
        if (!Utils.isEmpty(goodsHouseWarnList)) {
            goodsHouseWarnMapper.insertBatch(goodsHouseWarnList);
        }

        if (!Utils.isEmpty(goodsInitList)) {
            goodsInitMapper.insertBatch(goodsInitList);
            List<GoodsStock> goodsStockList = new ArrayList<>();
            List<GoodsCost> goodsCostList = new ArrayList<>();
            for (GoodsInit goodsInit : goodsInitList) {
                GoodsStock goodsStock = new GoodsStock();
                goodsStock.setId(UuidUtils.getUUID());
                goodsStock.setTime(new Date());
                goodsStock.setCompanyId(goods.getCompanyId());
                goodsStock.setHouseId(goodsInit.getHouseId());
                goodsStock.setGoodsId(goodsInit.getGoodsId());
                goodsStock.setNum(goodsInit.getInitNum());
                goodsStockList.add(goodsStock);

                GoodsCost goodsCost = new GoodsCost();
                goodsCost.setId(UuidUtils.getUUID());
                goodsCost.setCompanyId(goods.getCompanyId());
                goodsCost.setGoodsId(goodsInit.getGoodsId());
                goodsCost.setNumber(goodsInit.getInitNum());
                goodsCost.setCost(goodsInit.getInitCost());
                goodsCost.setTotalAmount(goodsInit.getInitAmt());
                goodsCostList.add(goodsCost);
            }
            goodsStockMapper.insertBatch(goodsStockList);
            goodsCostMapper.insertBatch(goodsCostList);
        }

        if (!Utils.isEmpty(goodsSnList)) {
            goodsSnMapper.insertBatch(goodsSnList);
            goodsSnLogMapper.insertBatch(goodsSnLogList);
        }
    }

    @Override
    public void update(Goods goods, List<GoodsAttr> goodsAttrList, List<GoodsUnit> goodsUnitList,
                       List<GoodsHouseWarn> goodsHouseWarnList,List<GoodsInit> goodsInitList,
                       List<GoodsSn> goodsSnList,List<GoodsSnLog> goodsSnLogList) {
        goodsMapper.updateById(goods);

        //先删除
        goodsAttrMapper.delete(new QueryWrapper<GoodsAttr>().eq("goods_id",goods.getId()));
        goodsUnitMapper.delete(new QueryWrapper<GoodsUnit>().eq("goods_id",goods.getId()));
        goodsHouseWarnMapper.delete(new QueryWrapper<GoodsHouseWarn>().eq("goods_id",goods.getId()));

        if (!goods.getSn()) {
            //关闭序列号，则需要删除序列号和序列号日志
            goodsSnMapper.delete(new QueryWrapper<GoodsSn>().eq("goods_id",goods.getId()));
            goodsSnLogMapper.delete(new QueryWrapper<GoodsSnLog>().eq("goods_id",goods.getId()));
        }

        if (!Utils.check(goodsMapper.check(goods.getId()))) {
            //没有被单据引用才能处理初期信息;如果被单据引用的话，则初期信息不允许被修改
            goodsInitMapper.delete(new QueryWrapper<GoodsInit>().eq("goods_id",goods.getId()));
            goodsSnMapper.delete(new QueryWrapper<GoodsSn>().eq("goods_id",goods.getId()));
            goodsSnLogMapper.delete(new QueryWrapper<GoodsSnLog>().eq("goods_id",goods.getId()));
            goodsStockMapper.delete(new QueryWrapper<GoodsStock>().eq("goods_id",goods.getId()));
            goodsCostMapper.delete(new QueryWrapper<GoodsCost>().eq("goods_id",goods.getId()));

            if (!Utils.isEmpty(goodsInitList)) {
                goodsInitMapper.insertBatch(goodsInitList);
                List<GoodsStock> goodsStockList = new ArrayList<>();
                List<GoodsCost> goodsCostList = new ArrayList<>();
                for (GoodsInit goodsInit : goodsInitList) {
                    GoodsStock goodsStock = new GoodsStock();
                    goodsStock.setId(UuidUtils.getUUID());
                    goodsStock.setTime(new Date());
                    goodsStock.setCompanyId(goods.getCompanyId());
                    goodsStock.setHouseId(goodsInit.getHouseId());
                    goodsStock.setGoodsId(goodsInit.getGoodsId());
                    goodsStock.setNum(goodsInit.getInitNum());
                    goodsStockList.add(goodsStock);

                    GoodsCost goodsCost = new GoodsCost();
                    goodsCost.setId(UuidUtils.getUUID());
                    goodsCost.setCompanyId(goods.getCompanyId());
                    goodsCost.setGoodsId(goodsInit.getGoodsId());
                    goodsCost.setNumber(goodsInit.getInitNum());
                    goodsCost.setCost(goodsInit.getInitCost());
                    goodsCost.setTotalAmount(goodsInit.getInitAmt());
                    goodsCostList.add(goodsCost);
                }
                goodsStockMapper.insertBatch(goodsStockList);
                goodsCostMapper.insertBatch(goodsCostList);
            }

            if (!Utils.isEmpty(goodsSnList)) {
                goodsSnMapper.insertBatch(goodsSnList);
                goodsSnLogMapper.insertBatch(goodsSnLogList);
            }
        }


        //再添加
        if (!Utils.isEmpty(goodsAttrList)) {
            goodsAttrMapper.insertBatch(goodsAttrList);
        }
        if (!Utils.isEmpty(goodsUnitList)) {
            goodsUnitMapper.insertBatch(goodsUnitList);
        }
        if (!Utils.isEmpty(goodsHouseWarnList)) {
            goodsHouseWarnMapper.insertBatch(goodsHouseWarnList);
        }
    }

    @Override
    public boolean checkName(String companyId, String id, String name) {
        return goodsMapper.selectCount(new QueryWrapper<Goods>().eq("company_id",companyId).eq("name",name).ne("id",id)) > 0;
    }

    @Override
    public boolean checkNo(String companyId, String id, String no) {
        return goodsMapper.selectCount(new QueryWrapper<Goods>().eq("company_id",companyId).eq("no",no).ne("id",id)) > 0;
    }

    @Override
    public void remove(Goods goods) {
        goodsSnMapper.delete(new QueryWrapper<GoodsSn>().eq("goods_id",goods.getId()));
        goodsSnLogMapper.delete(new QueryWrapper<GoodsSnLog>().eq("goods_id",goods.getId()));
        goodsStockMapper.delete(new QueryWrapper<GoodsStock>().eq("goods_id",goods.getId()));
        goodsCostMapper.delete(new QueryWrapper<GoodsCost>().eq("goods_id",goods.getId()));
        goodsAttrMapper.delete(new QueryWrapper<GoodsAttr>().eq("goods_id",goods.getId()));
        goodsUnitMapper.delete(new QueryWrapper<GoodsUnit>().eq("goods_id",goods.getId()));
        goodsHouseWarnMapper.delete(new QueryWrapper<GoodsHouseWarn>().eq("goods_id",goods.getId()));
        goodsMapper.deleteById(goods.getId());
    }

    @Override
    public void insert(List<Goods> goodsList, List<Type> typeList, List<Unit> unitList,
                            List<Attr> attrList, List<GoodsAttr> goodsAttrList, List<GoodsUnit> goodsUnitList,
                            List<GoodsHouseWarn> goodsHouseWarnList) {
        if (!Utils.isEmpty(typeList)) {
            typeMapper.insertBatch(typeList);
        }

        if (!Utils.isEmpty(unitList)) {
            unitMapper.insertBatch(unitList);
        }

        if (!Utils.isEmpty(attrList)) {
            attrMapper.insertBatch(attrList);
        }

        if (!Utils.isEmpty(goodsList)) {
            goodsMapper.insertBatch(goodsList);
        }

        if (!Utils.isEmpty(goodsAttrList)) {
            goodsAttrMapper.insertBatch(goodsAttrList);
        }
        if (!Utils.isEmpty(goodsUnitList)) {
            goodsUnitMapper.insertBatch(goodsUnitList);
        }
        if (!Utils.isEmpty(goodsHouseWarnList)) {
            goodsHouseWarnMapper.insertBatch(goodsHouseWarnList);
        }
    }

    @Override
    public void batchOpenSn(List<Goods> goodsList) {
        goodsMapper.batchOpenSn(goodsList);
    }

    @Override
    public void batchStatus(List<Goods> goodsList, Integer status) {
        goodsMapper.batchStatus(goodsList,status);
    }

    @Override
    public void batchMoveType(List<Goods> goodsList, String typeId) {
        goodsMapper.batchMoveType(goodsList,typeId);
    }

    @Override
    public void batchDelete(List<Goods> goodsList) {
        goodsSnLogMapper.batchDeleteByGoodsList(goodsList);
        goodsSnMapper.batchDeleteByGoodsList(goodsList);

        goodsStockMapper.batchDeleteByGoodsList(goodsList);
        goodsCostMapper.batchDeleteByGoodsList(goodsList);

        goodsAttrMapper.batchDeleteByGoodsList(goodsList);
        goodsUnitMapper.batchDeleteByGoodsList(goodsList);
        goodsHouseWarnMapper.batchDeleteByGoodsList(goodsList);
        goodsMapper.batchDelete(goodsList);
    }

    @Override
    public GoodsVo getVoByCode(String code, String companyId) {
        return goodsMapper.getVoByCode(code,companyId);
    }

    @Override
    public boolean beUsedByPacket(String id) {
        return packetGoodsMapper.selectCount(new QueryWrapper<PacketGoods>().eq("goods_id", id)) > 0;
    }

    @Override
    public Long checkCodeListBeUsed(String companyId, String id, List<String> codeList) {
        return goodsMapper.checkCodeListBeUsed(companyId,id,codeList);
    }
}
